import ctypes
from ctypes import wintypes
import struct

# 定义必要的类型和常量
PVOID = ctypes.c_void_p
NTSTATUS = ctypes.c_long
ULONG = wintypes.ULONG
SIZE_T = ctypes.c_size_t
HANDLE = wintypes.HANDLE
PHANDLE = ctypes.POINTER(HANDLE)
ACCESS_MASK = wintypes.DWORD


# 定义shellcode
ShellCode = bytes([0x40,0x55,0x53,0x56,0x57,0x41,0x54,0x41,0x56,0x48,0x8D,0x6C,0x24,0xD1,0x48,0x81,
0xEC,0x98,0x00,0x00,0x00,0x48,0x8B,0x41,0x20,0x45,0x33,0xC0,0x44,0x8B,0x49,0x08,
0x48,0x8B,0x79,0x28,0x4C,0x8B,0x71,0x40,0x48,0x8B,0x19,0x4C,0x8B,0x61,0x10,0x48,
0x8B,0x71,0x18,0x48,0x89,0x45,0xD7,0x48,0x8B,0x41,0x30,0x48,0x89,0x45,0xCF,0x48,
0x8B,0x41,0x38,0x48,0x89,0x45,0xDF,0x48,0x8B,0x41,0x48,0x48,0x89,0x45,0xEF,0x48,
0x89,0x7D,0x7F,0x4C,0x89,0x75,0xE7,0x4C,0x89,0x45,0x67,0x49,0x83,0xF9,0x40,0x0F,
0x86,0x2A,0x04,0x00,0x00,0xB8,0x4D,0x5A,0x00,0x00,0x66,0x39,0x03,0x0F,0x85,0x1C,
0x04,0x00,0x00,0x48,0x63,0x4B,0x3C,0x48,0x8D,0x81,0x08,0x01,0x00,0x00,0x4C,0x3B,
0xC8,0x0F,0x82,0x08,0x04,0x00,0x00,0x81,0x3C,0x19,0x50,0x45,0x00,0x00,0x4C,0x89,
0xAC,0x24,0x90,0x00,0x00,0x00,0x4C,0x8D,0x2C,0x19,0x0F,0x85,0xE7,0x03,0x00,0x00,
0x41,0x0F,0xB7,0x45,0x16,0xB9,0x02,0x20,0x00,0x00,0x66,0x23,0xC1,0x66,0x3B,0xC1,
0x0F,0x85,0xD1,0x03,0x00,0x00,0xB8,0xF0,0x00,0x00,0x00,0x66,0x41,0x39,0x45,0x14,
0x0F,0x85,0xC1,0x03,0x00,0x00,0x45,0x0F,0xB7,0x55,0x06,0x33,0xD2,0x45,0x85,0xD2,
0x0F,0x84,0x82,0x00,0x00,0x00,0x49,0x8D,0x8D,0x18,0x01,0x00,0x00,0x0F,0x1F,0x00,
0x8B,0x41,0x04,0x03,0x01,0x41,0x3B,0xC1,0x0F,0x87,0x99,0x03,0x00,0x00,0xFF,0xC2,
0x48,0x83,0xC1,0x28,0x41,0x3B,0xD2,0x7C,0xE7,0x45,0x8B,0x5D,0x38,0x33,0xD2,0x41,
0x8B,0x45,0x54,0x49,0x8B,0xFA,0xFF,0xC8,0x4D,0x8D,0x95,0x18,0x01,0x00,0x00,0x41,
0x03,0xC3,0x41,0xF7,0xF3,0x44,0x8B,0xC8,0x45,0x0F,0xAF,0xCB,0x0F,0x1F,0x40,0x00,
0x41,0x8B,0x4A,0xF8,0x41,0x8D,0x43,0xFF,0x41,0x39,0x0A,0x41,0x0F,0x4F,0x0A,0x33,
0xD2,0x41,0x03,0x4A,0xFC,0x4D,0x8D,0x52,0x28,0x03,0xC1,0x41,0xF7,0xF3,0x41,0x0F,
0xAF,0xC3,0x44,0x3B,0xC8,0x41,0x0F,0x4D,0xC1,0x44,0x8B,0xC8,0x48,0x83,0xEF,0x01,
0x75,0xCE,0x48,0x8B,0x7D,0x7F,0xEB,0x15,0x41,0x8B,0x4D,0x38,0x41,0x8B,0x45,0x54,
0xFF,0xC8,0x03,0xC1,0xF7,0xF1,0x44,0x8B,0xC8,0x44,0x0F,0xAF,0xC9,0x45,0x85,0xC9,
0x0F,0x84,0x11,0x03,0x00,0x00,0x49,0x63,0xC1,0x48,0x8D,0x55,0x67,0x4C,0x8D,0x4D,
0xC7,0xC7,0x44,0x24,0x28,0x40,0x00,0x00,0x00,0x48,0xC7,0xC1,0xFF,0xFF,0xFF,0xFF,
0x48,0x89,0x45,0xC7,0xC7,0x44,0x24,0x20,0x00,0x10,0x00,0x00,0xFF,0xD6,0x4C,0x8B,
0x45,0x67,0x4D,0x85,0xC0,0x0F,0x84,0xDC,0x02,0x00,0x00,0x45,0x0F,0xB7,0x4D,0x06,
0x45,0x33,0xDB,0x41,0x8B,0x45,0x54,0x43,0x8D,0x0C,0x89,0x8D,0x0C,0xC8,0x48,0x63,
0xD1,0x85,0xC9,0x7E,0x24,0x41,0x8B,0xCB,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00,
0x0F,0xB6,0x04,0x19,0x42,0x88,0x04,0x01,0x48,0xFF,0xC1,0x4C,0x8B,0x45,0x67,0x48,
0x3B,0xCA,0x7C,0xEC,0x45,0x0F,0xB7,0x4D,0x06,0x45,0x8B,0xD3,0x66,0x45,0x3B,0xD9,
0x73,0x5B,0x49,0x8D,0x95,0x18,0x01,0x00,0x00,0x0F,0x1F,0x80,0x00,0x00,0x00,0x00,
0x8B,0x4A,0xFC,0x85,0xC9,0x74,0x35,0x8B,0x02,0x85,0xC0,0x74,0x2F,0x4D,0x8D,0x0C,
0x08,0x49,0x8B,0xCB,0x0F,0x1F,0x40,0x00,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00,
0x8B,0x42,0x04,0x48,0x03,0xC1,0x0F,0xB6,0x04,0x18,0x42,0x88,0x04,0x09,0x48,0xFF,
0xC1,0x8B,0x02,0x48,0x3B,0xC8,0x72,0xE8,0x4C,0x8B,0x45,0x67,0x41,0x0F,0xB7,0x45,
0x06,0x41,0xFF,0xC2,0x48,0x83,0xC2,0x28,0x44,0x3B,0xD0,0x7C,0xB3,0x41,0x8B,0x85,
0xB0,0x00,0x00,0x00,0x4C,0x89,0xBC,0x24,0x88,0x00,0x00,0x00,0x85,0xC0,0x0F,0x84,
0xB8,0x00,0x00,0x00,0x41,0x83,0xBD,0xB4,0x00,0x00,0x00,0x00,0x0F,0x86,0xAA,0x00,
0x00,0x00,0x41,0x8B,0x0C,0x00,0x4D,0x8D,0x14,0x00,0x45,0x8B,0x4A,0x04,0x49,0x8B,
0xD8,0x49,0x2B,0x5D,0x30,0x41,0x03,0xC9,0x0F,0x84,0x8E,0x00,0x00,0x00,0xB9,0x00,
0x30,0x00,0x00,0xBE,0x00,0xA0,0x00,0x00,0x41,0xBF,0x00,0xF0,0x00,0x00,0x66,0x90,
0x41,0x8B,0xC1,0x49,0x8B,0xD3,0x48,0x83,0xE8,0x08,0x48,0xD1,0xE8,0x4C,0x63,0xD8,
0x85,0xC0,0x7E,0x4B,0x0F,0x1F,0x40,0x00,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00,
0x45,0x0F,0xB7,0x4C,0x52,0x08,0x41,0x0F,0xB7,0xC1,0x66,0x41,0x23,0xC7,0x66,0x3B,
0xC1,0x74,0x05,0x66,0x3B,0xC6,0x75,0x1B,0x41,0x8B,0x0A,0x41,0x81,0xE1,0xFF,0x0F,
0x00,0x00,0x4B,0x8D,0x04,0x08,0x48,0x01,0x1C,0x01,0xB9,0x00,0x30,0x00,0x00,0x4C,
0x8B,0x45,0x67,0x48,0xFF,0xC2,0x49,0x3B,0xD3,0x7C,0xC5,0x45,0x8B,0x4A,0x04,0x41,
0x8B,0xC1,0x41,0xBB,0x00,0x00,0x00,0x00,0x4C,0x03,0xD0,0x41,0x8B,0x0A,0x45,0x8B,
0x4A,0x04,0x41,0x03,0xC9,0xB9,0x00,0x30,0x00,0x00,0x75,0x84,0x41,0x8B,0x85,0x90,
0x00,0x00,0x00,0x48,0x85,0xC0,0x0F,0x84,0x53,0x01,0x00,0x00,0x4E,0x8D,0x3C,0x00,
0x4C,0x89,0x5D,0x6F,0x41,0x8B,0x07,0x85,0xC0,0x0F,0x84,0xEE,0x00,0x00,0x00,0x90,
0x41,0x8B,0x57,0x0C,0x48,0x8D,0x4D,0xF7,0x45,0x8B,0x77,0x10,0x49,0x03,0xD0,0x8B,
0xF0,0x4D,0x03,0xF0,0x49,0x03,0xF0,0xFF,0xD7,0x41,0xB0,0x01,0x48,0x8D,0x55,0xF7,
0x48,0x8D,0x4D,0x07,0xFF,0x55,0xCF,0x4C,0x8D,0x4D,0x6F,0x33,0xD2,0x4C,0x8D,0x45,
0x07,0x33,0xC9,0xFF,0x55,0xD7,0x48,0x8D,0x4D,0x07,0xFF,0x55,0xDF,0x48,0x8B,0x4D,
0x6F,0x48,0x85,0xC9,0x0F,0x84,0xF1,0x00,0x00,0x00,0x48,0x8B,0x06,0x33,0xD2,0x8B,
0xDA,0x48,0x85,0xC0,0x74,0x7F,0x8B,0xFA,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00,
0x48,0x89,0x55,0x77,0x48,0x85,0xC0,0x79,0x11,0x66,0x85,0xC0,0x0F,0x84,0xC9,0x00,
0x00,0x00,0x44,0x0F,0xB7,0xC0,0x33,0xD2,0xEB,0x23,0x4C,0x8B,0x45,0x67,0x49,0x8D,
0x50,0x02,0x48,0x03,0xD0,0x0F,0x84,0xB4,0x00,0x00,0x00,0x48,0x8D,0x4D,0xF7,0xFF,
0x55,0x7F,0x48,0x8B,0x4D,0x6F,0x48,0x8D,0x55,0xF7,0x45,0x33,0xC0,0x4C,0x8D,0x4D,
0x77,0x41,0xFF,0xD4,0x48,0x8B,0x45,0x77,0x48,0x85,0xC0,0x0F,0x84,0x8A,0x00,0x00,
0x00,0x48,0xFF,0xC3,0x49,0x89,0x04,0x3E,0x48,0x8B,0x04,0xDE,0x48,0x8D,0x3C,0xDD,
0x00,0x00,0x00,0x00,0x48,0x85,0xC0,0x74,0x08,0x48,0x8B,0x4D,0x6F,0x33,0xD2,0xEB,
0x8F,0x48,0x8B,0x7D,0x7F,0x41,0x8B,0x47,0x14,0x49,0x83,0xC7,0x14,0x4C,0x8B,0x45,
0x67,0x85,0xC0,0x0F,0x85,0x17,0xFF,0xFF,0xFF,0x4C,0x8B,0x75,0xE7,0x41,0x8B,0x5D,
0x28,0xBA,0x01,0x00,0x00,0x00,0x4D,0x89,0x45,0x30,0x33,0xC9,0x4C,0x8B,0x45,0x67,
0x49,0x03,0xD8,0xFF,0xD3,0x85,0xC0,0x75,0x32,0x4C,0x8B,0x45,0x67,0x33,0xD2,0x33,
0xC9,0xFF,0xD3,0x83,0xF8,0x01,0x75,0x23,0x48,0x8B,0x4D,0x6F,0x41,0xFF,0xD6,0x85,
0xC0,0x75,0x18,0x41,0xB9,0x00,0x80,0x00,0x00,0x4C,0x8D,0x45,0xC7,0x48,0x8D,0x55,
0x67,0x48,0xC7,0xC1,0xFF,0xFF,0xFF,0xFF,0xFF,0x55,0xEF,0x4C,0x8B,0x45,0x67,0x4C,
0x8B,0xBC,0x24,0x88,0x00,0x00,0x00,0x4C,0x8B,0xAC,0x24,0x90,0x00,0x00,0x00,0x49,
0x8B,0xC0,0x48,0x81,0xC4,0x98,0x00,0x00,0x00,0x41,0x5E,0x41,0x5C,0x5F,0x5E,0x5B,
0x5D,0xC3 ])

# 定义 NtCreateThreadEx 函数原型
ntdll = ctypes.WinDLL('ntdll')
NtCreateThreadEx = ctypes.WINFUNCTYPE(
    NTSTATUS,
    PHANDLE,
    ACCESS_MASK,
    PVOID,
    HANDLE,
    PVOID,
    PVOID,
    ULONG,
    SIZE_T,
    SIZE_T,
    SIZE_T,
    PVOID
)(("NtCreateThreadEx", ntdll))

# 定义 Windows API 函数
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
VirtualAllocEx = kernel32.VirtualAllocEx
VirtualAllocEx.argtypes = [HANDLE, PVOID, ctypes.c_size_t, wintypes.DWORD, wintypes.DWORD]
VirtualAllocEx.restype = PVOID

GetLastError = kernel32.GetLastError
GetLastError.argtypes = []
GetLastError.restype = wintypes.DWORD


WriteProcessMemory = kernel32.WriteProcessMemory
WriteProcessMemory.argtypes = [HANDLE, PVOID, PVOID, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)]
WriteProcessMemory.restype = wintypes.BOOL

VirtualFreeEx = kernel32.VirtualFreeEx
VirtualFreeEx.argtypes = [HANDLE, PVOID, ctypes.c_size_t, wintypes.DWORD]
VirtualFreeEx.restype = wintypes.BOOL

GetProcAddress = kernel32.GetProcAddress
GetProcAddress.argtypes = [wintypes.HMODULE, wintypes.LPCSTR]
GetProcAddress.restype = PVOID

GetModuleHandleA = kernel32.GetModuleHandleA
GetModuleHandleA.argtypes = [wintypes.LPCSTR]
GetModuleHandleA.restype = wintypes.HMODULE

CloseHandle = kernel32.CloseHandle
CloseHandle.argtypes = [HANDLE]
CloseHandle.restype = wintypes.BOOL

CreateRemoteThread = kernel32.CreateRemoteThread
CreateRemoteThread.argtypes = [HANDLE, PVOID, ctypes.c_size_t, PVOID, PVOID, wintypes.DWORD, PVOID]
CreateRemoteThread.restype = HANDLE

WaitForSingleObject = kernel32.WaitForSingleObject
WaitForSingleObject.argtypes = [HANDLE, wintypes.DWORD]
WaitForSingleObject.restype = wintypes.DWORD

GetExitCodeThread = kernel32.GetExitCodeThread
GetExitCodeThread.argtypes = [HANDLE, ctypes.POINTER(wintypes.DWORD)]
GetExitCodeThread.restype = wintypes.BOOL

# 常量定义
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
MEM_RELEASE = 0x8000
PAGE_EXECUTE_READWRITE = 0x40
THREAD_ALL_ACCESS = 0x1FFFFF
INFINITE = 0xFFFFFFFF


class CInject:
    @staticmethod
    def Inject(hProcess, Dll, size):
        param = None
        hThread = None
        try:
            # 验证进程句柄
            if not hProcess or hProcess == HANDLE(-1):
                print(f"无效的进程句柄: {GetLastError()}")
                return False,GetLastError()
                
            param = (ctypes.c_int64 * 10)()
            hNtdll = GetModuleHandleA(b"ntdll.dll")
            if not hNtdll:
                return False,GetLastError()
    
            # 获取参数地址
            param[0] = VirtualAllocEx(hProcess, None, size + 1242, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)
            if not param[0]:
                return False,GetLastError()
            param[1]=size
            func_names = [
                b"LdrGetProcedureAddress",
                b"NtAllocateVirtualMemory",
                b"LdrLoadDll",
                b"RtlInitAnsiString",
                b"RtlAnsiStringToUnicodeString",
                b"RtlFreeUnicodeString",
                b"LdrUnloadDll",
                b"NtFreeVirtualMemory"
            ]
    
            for i in range(0, 8):
                param[i+2] = GetProcAddress(hNtdll, func_names[i])
                if not param[i+2]:
                    return False,GetLastError()
    
            # 写入 ShellCode 和参数
            code_size = len(ShellCode)
            written = ctypes.c_size_t(0)
    
            # 写入 DLL 数据
            if not WriteProcessMemory(hProcess, param[0], Dll, size, ctypes.byref(written)):
                return False,GetLastError()
    
            # 写入 ShellCode
            shellcode_addr = param[0] + size
            if not WriteProcessMemory(hProcess, shellcode_addr, ShellCode, code_size, ctypes.byref(written)):
                return False,GetLastError()
    
            # 写入参数
            param_addr = shellcode_addr + code_size
            param_size = ctypes.sizeof(param)
            if not WriteProcessMemory(hProcess, param_addr, ctypes.byref(param), param_size, ctypes.byref(written)):
                return False,GetLastError()
    
            # 创建远程线程
            hThread = HANDLE()
            status = NtCreateThreadEx(
                ctypes.byref(hThread),
                THREAD_ALL_ACCESS,
                None,
                hProcess,
                shellcode_addr,
                param_addr,
                0, 0, 0, 0, None
            )
            if status < 0 or not hThread:
                return False,GetLastError()
    
            WaitForSingleObject(hThread, INFINITE)
    
            exit_code = wintypes.DWORD()
            GetExitCodeThread(hThread, ctypes.byref(exit_code))
    
            if exit_code.value >= 0x80000000:
                return False,GetLastError()
    
            return True,0
    
        except Exception as e:
            print(f"Inject error: {str(e)},错误码:{GetLastError()}")
            return False,GetLastError()
        finally:
            if param and param[0]:
                VirtualFreeEx(hProcess, param[0], 0, MEM_RELEASE)
            if hThread:
                CloseHandle(hThread)

    @staticmethod
    def RemoteInject(hProcess, dllPath):
        pRemoteMemory = None
        hThread = None
        try:
            dll_path_bytes = dllPath.encode('utf-8') + b'\x00'
            pRemoteMemory = VirtualAllocEx(hProcess, None, len(dll_path_bytes), MEM_COMMIT | MEM_RESERVE,
                                           PAGE_EXECUTE_READWRITE)
            if not pRemoteMemory:
                print(f"Allocation failed: {ctypes.GetLastError()}")
                return False

            written = ctypes.c_size_t(0)
            if not WriteProcessMemory(hProcess, pRemoteMemory, dll_path_bytes, len(dll_path_bytes), ctypes.byref(written)):
                print(f"Write failed: {ctypes.GetLastError()}")
                return False

            hKernel32 = GetModuleHandleA(b"kernel32.dll")
            pLoadLibraryA = GetProcAddress(hKernel32, b"LoadLibraryA")
            if not pLoadLibraryA:
                print(f"GetProcAddress failed: {ctypes.GetLastError()}")
                return False

            hThread = CreateRemoteThread(hProcess, None, 0, pLoadLibraryA, pRemoteMemory, 0, None)
            if not hThread:
                print(f"CreateRemoteThread failed: {ctypes.GetLastError()}")
                return False

            WaitForSingleObject(hThread, INFINITE)
            return True

        except Exception as e:
            print(f"RemoteInject error: {str(e)}")
            return False
        finally:
            if pRemoteMemory:
                VirtualFreeEx(hProcess, pRemoteMemory, 0, MEM_RELEASE)
            if hThread:
                CloseHandle(hThread)